package com.shine.output {
	import flash.display.DisplayObject;
	import flash.display.GradientType;
	import flash.display.Shape;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.TextEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	public class Output extends Sprite {
		public static var maxLength:int = 1000;
		public static var maxLine:int = 50;
		private static var instance:Output;
		private static var autoExpand:Boolean = true;
		private static var isStrong:Boolean = false;
		private var history:Array = new Array();
		private var search_label:TextField;
		private var output_txt:TextField;
		private var titleBar:Sprite;
		private var barLabel:TextField;
		private var thiz_stage:Stage;
		[Embed(source="outputImages/delete.gif")]
		private var delete_icon:Class;
		[Embed(source="outputImages/search.gif")]
		private var search_icon:Class;
		[Embed(source="outputImages/pin.gif")]
		private var pin_icon:Class;
		[Embed(source="outputImages/unpin.gif")]
		private var unpin_icon:Class;
		[Embed(source="outputImages/close.gif")]
		private var close_icon:Class;
		
		public function Output(outputHeight:uint = 150,strong:Boolean = false){
			if (instance && instance.parent){
				instance.parent.removeChild(this);
			}
			
			instance = this;
			isStrong = strong;
			
			addChild(newOutputField(outputHeight));
			addChild(newTitleBar());
			
			addEventListener(Event.ADDED, added);
			addEventListener(Event.REMOVED, removed);
		}
		
		public static function push(str:*,level:uint = 1):void {
			if (!instance) return;
			instance.addMsg(str,level);
		}
		
		public static function clear(e:MouseEvent = null):void {
			if (!instance) return;
			instance.output_txt.text = "";
			if(instance.search_label) instance.search_label.text = "";
			instance.history = new Array();
		}
		
		public function setVersionText(versionStr:String):void
		{
			barLabel.appendText( "  " + versionStr );
		}
		
		private function addMsg(str:*,level:uint):void{
			if(isStrong){
				history.push({s:str,c:getColorTextByLevel(str,level)});
				
				if(history.length > maxLine) history.shift();
				if(thiz_stage && thiz_stage.contains(this)) updataHtmlText();
			}else{
				output_txt.appendText(str+"\n");
				if (output_txt.length > maxLength) {
					output_txt.text = output_txt.text.slice(-maxLength);
				}
				output_txt.scrollV = output_txt.maxScrollV;
			}
			
			if (autoExpand && !output_txt.visible) toggleCollapse();
		}
		
		private function updataHtmlText(e:Event = null):void{
			if(!output_txt.visible && !isStrong) return ;
			var str:String = "";
			var len:uint = instance.history.length;
			
			var i :uint;
			if(search_label.text.length > 0){
				var serach_str:String = search_label.text;
				for( i  = 0 ; i < len ; i ++ ){
					var s:String = instance.history[i].s;
					if(s.indexOf(serach_str) != -1){
						str = str + instance.history[i].c + "<br>";
					}
				}
			}else{
				for( i  = 0 ; i < len ; i ++ ){
					str = str + instance.history[i].c + "<br>";
				}
			}
			instance.output_txt.text = "";
			instance.output_txt.htmlText = str;
			output_txt.scrollV = output_txt.maxScrollV;
		}
		
		private function newOutputField(outputHeight:uint):TextField {
			output_txt = new TextField();
			output_txt.type = TextFieldType.INPUT;
			output_txt.border = true;
			output_txt.borderColor = 0;
			output_txt.background = true;
			output_txt.backgroundColor = 0xFFFFFF;
			output_txt.height = outputHeight;
			output_txt.multiline = true;
			var format:TextFormat = output_txt.getTextFormat();
			format.font = "Tahoma,宋体";
			output_txt.setTextFormat(format);
			output_txt.defaultTextFormat = format;
			return output_txt;
		}
		
		private function newTitleBar():Sprite
		{
			//bar
			var barGraphics:Sprite = new Sprite();
			barGraphics.name = "bar";
			var colors:Array = new Array(0xEFEFF1, 0xC9CACF, 0xEFEFF1);
			var alphas:Array = new Array(1, 1, 1);
			var ratios:Array = new Array(0, 50, 255);
			var gradientMatrix:Matrix = new Matrix();
			gradientMatrix.createGradientBox(20, 20, Math.PI/2, 0, 0);
			barGraphics.graphics.lineStyle(0,0x6C6C7B);
			barGraphics.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, gradientMatrix);
			barGraphics.graphics.drawRect(0, 0, 20, 20);
			
			//logo
			/* var logo:DisplayObject = new information_icon() as DisplayObject;
			logo.x = logo.y = 2; */
			
			barLabel = new TextField();
			barLabel.mouseEnabled = false;
			barLabel.selectable = false;
			barLabel.autoSize = TextFieldAutoSize.LEFT;
			barLabel.text = "Tracer Output";
			var format:TextFormat = barLabel.getTextFormat();
			format.font = "Tahoma,宋体,_sans";
			barLabel.setTextFormat(format);
			barLabel.x = 2;
			
			if(isStrong){
				//tools
				var tools:Sprite = new Sprite();
				tools.name = "tools";
				var search_icon:DisplayObject = new search_icon() as DisplayObject;
				
				var search_bg:Shape = new Shape();
				search_bg.graphics.beginFill(0x94959D);
				search_bg.graphics.drawRect(0,0,80,17);
				search_bg.graphics.beginFill(0xD6D6D6);
				search_bg.graphics.drawRect(1,1,78,15);
				
				search_label = new TextField();
				search_label.type = TextFieldType.INPUT;
				search_label.width = 80;
				search_label.height = 18;
				search_label.defaultTextFormat = new TextFormat("Tahoma");
				search_label.addEventListener(KeyboardEvent.KEY_UP,updataHtmlText);
				search_bg.x = search_label.x = search_icon.width + 4;
				
				var clear_but:Sprite = new Sprite();
				var clear_but_up:DisplayObject = new delete_icon() as DisplayObject;
				clear_but.addChild(clear_but_up);
				clear_but.addEventListener(MouseEvent.CLICK,clear);
				
				clear_but.x = search_bg.x + search_bg.width + 4;
				
				var pin_but:Sprite = new Sprite();
				var pin:DisplayObject = new pin_icon() as DisplayObject;
				pin.name = "pin";
				var unpin:DisplayObject = new unpin_icon() as DisplayObject;
				unpin.name = "unpin";
				
				pin_but.addChild(pin);
				pin_but.addChild(unpin);
				unpin.visible = false;
				pin_but.x = clear_but.x + clear_but.width + 4;
				pin_but.y = 3;
				pin_but.addEventListener(MouseEvent.CLICK,pinCollapse);
				
				var close_but:Sprite = new Sprite();
				
				var close_up:DisplayObject = new close_icon() as DisplayObject;
				close_but.addChild(close_up);
				close_but.x = pin_but.x + pin_but.width + 4;
				close_but.addEventListener(MouseEvent.CLICK,closeButtonHanlder);
				
				//addChild
				tools.addChild(search_icon);
				tools.addChild(search_bg);
				tools.addChild(search_label);
				tools.addChild(clear_but);
				tools.addChild(pin_but);
				tools.addChild(close_but);
				tools.y = 2;
			}
			
			titleBar = new Sprite();
			titleBar.addChild(barGraphics);
			//titleBar.addChild(logo);
			if(isStrong) titleBar.addChild(tools);
			titleBar.addChild(barLabel);
			return titleBar;
		}
		
		private static function getColorTextByLevel(str:String,level:uint):String{
			var c:String;
			switch (level){
					case 1 : 
						c = "#666666";
					break;
					case 2 : 
						c = "#00CC33";
					break;
					case 4 : 
						c = "#0066FF";
					break;
					case 8 : 
						c = "#FFCC00";
					break;
					case 16 : 
						c = "#FF0000";
					break;
					case 32 : 
						c = "#990000";
					break;
					default :
						c = "#000000";
					break;
				}
			return ("<font color='"+c+"'>" + str + "</font>");
		}
		
		
		private function added(evt:Event):void {
			thiz_stage = stage;
			stage.addEventListener(Event.RESIZE, fitToStage);
			stage.addEventListener(KeyboardEvent.KEY_UP,shortcutKey);
			titleBar.getChildByName("bar").addEventListener(MouseEvent.CLICK, toggleCollapse);
			fitToStage();
		}
		private function removed(evt:Event):void {
			stage.removeEventListener(Event.RESIZE, fitToStage);
			titleBar.removeEventListener(MouseEvent.CLICK, toggleCollapse);
		}
		
		private function toggleCollapse(evt:Event = null):void {
			if (!instance) return;
			output_txt.visible = !output_txt.visible;
			updataHtmlText();
			fitToStage(evt);
		}
		
		private function pinCollapse(e:MouseEvent):void{
			var pin:DisplayObject = e.target.getChildByName("pin");
			var unpin:DisplayObject = e.target.getChildByName("unpin");
			
			pin.visible = !pin.visible;
			unpin.visible = !unpin.visible;
			
			autoExpand = pin.visible;
		}
		
		private function fitToStage(evt:Event = null):void {
			if (!stage) return;
			output_txt.width = stage.stageWidth;
			output_txt.y = stage.stageHeight - output_txt.height;
			titleBar.y = (output_txt.visible) ? output_txt.y - titleBar.height : stage.stageHeight - titleBar.height;
			titleBar.getChildByName("bar").width = stage.stageWidth;
			
			if(isStrong){
				var tools:DisplayObject = titleBar.getChildByName("tools");
				tools.x = stage.stageWidth - tools.width - 4;
			}
		}
		
		private function closeButtonHanlder(e:MouseEvent = null):void{
			if(thiz_stage)
				if(thiz_stage.contains(this))thiz_stage.removeChild(this);
		}
		
		private function shortcutKey(e:KeyboardEvent):void{
			if(e.shiftKey && e.altKey && e.ctrlKey && e.keyCode == 79){
				if(instance && thiz_stage){
					if(thiz_stage.contains(this)){
						thiz_stage.removeChild(this);
					}else{
						thiz_stage.addChild(this);
						updataHtmlText();
					}
				}
			}
		}
		/**
		* @example The following code sets the volume level for your sound: <listing version="3.0" > var mySound:Sound = new Sound(); mySound.setVolume(VOL_HIGH); </listing> 
		* 
		*/		
	}
}